\documentclass[a4paper,10pt]{article}

\usepackage[utf8]{inputenc}
\usepackage{t1enc}

\usepackage[utf8]{inputenc}
\usepackage{t1enc}
\usepackage[spanish]{babel}
\usepackage[pdftex,usenames,dvipsnames]{color}
\usepackage[pdftex]{graphicx}
\usepackage{enumerate}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage[table]{xcolor}
\usepackage[small,bf]{caption}
\usepackage{float}
\usepackage{subfig}
\usepackage{listings}
\usepackage{bm}
\usepackage{times}

\begin{document}
\setcounter{secnumdepth}{5}
\setcounter{tocdepth}{5}

\renewcommand{\lstlistingname}{C\'odigo Fuente}
\lstloadlanguages{Octave} 
\lstdefinelanguage{MyOctave}[]{Octave}{
        deletekeywords={beta,det},
        morekeywords={repmat}
} 
\lstset{
        language=MyOctave,
        stringstyle=\ttfamily,
        showstringspaces = false,
        basicstyle=\footnotesize\ttfamily,
        commentstyle=\color{gray},
        keywordstyle=\bfseries,
        numbers=left,
        numberstyle=\ttfamily\footnotesize,
        stepnumber=1,                   
        framexleftmargin=0.20cm,
        numbersep=0.37cm,              
        backgroundcolor=\color{white},
        showspaces=false,
        showtabs=false,
        frame=l,
        tabsize=4,
        captionpos=b,               
        breaklines=true,             
        breakatwhitespace=false,      
        mathescape=true
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%% begin TITLE PAGE %%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{titlepage}
        \vfill
        \thispagestyle{empty}
        \begin{center}
                \includegraphics{./images/itba_logo.png}
                \vfill
                \Huge{Trabajo Pr\'actico Especial - Entrega Final}\\
                \vspace{1cm}
                \Huge{Protocolos de Comunicaci\'on}\\
        \end{center}
        \vfill
        \large{
        \begin{tabular}{lcr}
                Crespo, Alvaro && 50758 \\
                Susnisky, Dar\'io && 50592\\
                Wassington, Axel && 50124\\
        \end{tabular}
}
        \vspace{2cm}
        \begin{center}
                \large{6 de Junio de 2012}\\
        \end{center}
\end{titlepage}
\newpage

\setcounter{page}{1}

\tableofcontents

\newpage

\section{Introducci\'on}

Se ha desarrollado una aplicacici\'on cuyo objetivo principal es la de realizar la funcionalidad de proxy entre clientes 
y origin servers. La aplicaci\'on deb\'ia cumplir ciertos requerimientos funcionales transform\'andolo en algo mucho 
m\'as complejo que un simple proxy "pasamanos". Estos requerimientos inclu\'ian concurrencia, conexiones persistentes, 
bloqueos y transformaciones sobre los pedidos, sistema de monitoreo y logging. 

Para el desarrollo de la configuraci\'on y el monitoreo del proxy fue necesario implementar protocolos propios para
poder interactuar con el proxy.

\newpage
\section{RFCs relevantes para el desarrollo de este trabajo pr\'actico}

\begin{itemize}
    \item RFC 2616 --- Hypertext Transfer Protocol -- HTTP/1.1
    \item RFC 2068 --- Hypertext Transfer Protocol -- HTTP/1.1
    \item RFC 1945 --- Hypertext Transfer Protocol -- HTTP/1.0
    \item RFC 2119 --- Key words for use in RFCs to Indicate Requirement Levels
    \item RFC 822  --- Standard for the format of ARPA Internet text messages
    \item RFC 1590 --- Media Type Registration Procedure
    \item RFC 2046 --- Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types
    \item RFC 2047 --- MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text
    \item RFC 2396 --- Uniform Resource Identifiers (URI): Generic Syntax
    \item RFC 1766 --- Tags for the Identification of Languages
    \item RFC 1738 --- Uniform Resource Locators (URL)

\end{itemize}


\newpage
\section{Protocolos desarrollados}

    \subsection{Introducci\'on}

    A continuaci\'on se presentar\'a las especificaciones para dar un breve entendimiento 
    de los protocolos para acceder al monitoreo del proxy y para acceder a la configuraci\'on del mismo.

        \subsubsection{Prop\'osito}

        Tanto el protocolo para acceder al monitoreo del proxy como el protocolo para acceder a la 
        configuraci\'on de este son protocolos que funcionan a nivel aplicaci\'on para sistemas de informaci\'on.

        El protocolo para configurar al proxy pretende enviar los datos crudos para lograr su objetivo. En cambio, 
        el protocolo para el monitoreo requiere un nivel de autenticaci\'on para luego recibir la informaci\'on 
        deseada. 

        Ninguno de los dos protocolos posee configuraci\'on extendida dando uso espec\'ifico tanto para el monitoreo 
        como para la configuraci\'on particular de un proxy.

        \subsubsection{Requerimientos}

        Las palabras DEBE, NO DEBE, REQUERIDO, HARA, NO HARA, DEBERIA, NO DEBERIA, 
        RECOMENDADO, PUEDE y OPCIONAL se deben interpretar tal y como describe el 
        RFC2119 (http://www.rfc-es.org/rfc/rfc2119-es.txt).

    \subsection{Convenciones de notaci\'on y gram\'atica}

        Para referirse a convenciones de notaciones y gram\'aticas (particularmente sobre BNF aumentada y reglas
        b\'asicas) referirse a la secci\'on 2 (tanto 2.1 como 2.2) del RFC 2616.

\newpage

    \subsection{Protocolo para acceder al monitoreo del proxy}

        \paragraph*{Funcionamiento general}

        Este protocolo es un protocolo de pedido y respuesta con el objetivo de obtener informaci\'on 
        de monitoreo del proxy. Para poder realizar la comunicaci\'on correctamente se env\'ian datos 
        de autenticaci\'on en el pedido del cliente. Para que el servidor realmente devuelva la 
        informaci\'on correcta, es importante que la autenticaci\'on sea correcta. El formato y la 
        informaci\'on enviada tanto en el pedido como en la respuesta ser\'an aclarados en secciones 
        posteriores. A la primer idea del protocolo se suma el concepto de enviar la versi\'on del protocolo.
        En este informe se detalla la 1.0

        Es necesario precisar que toda conexi\'on dada por este protocolo es iniciada por una aplicaci\'on cliente (por ejemplo netcat)
         y en este caso la aplicaci\'on funciona de servidor para proveer a un usuario datos 
        posiblemente relevantes de la misma.

        Para poder utilizar este protocolo se reservar\'a un puerto especifico que debe ser conocido 
        por el cliente para poder establecer la conexi\'on. No es exclusivo, pero se asume que este 
        protocolo es montado sobre TCP/IP, corroborando as\'i integridad y seguridad en la transferencia 
        de los datos. Para este protocolo el puerto elegido por defecto es el 2020 aunque el mismo puede 
        ser modificado en el archivo .properties.

        Por \'ultimo es util resaltar que en cada pedido de este protocolo se esta generando una nueva 
        conexi\'on y que al finalizar el pedido y la respuesta se cierra la conexi\'on.

        \subsubsection{Mensaje del Protocolo}
            Los mensajes del protocolo consisten de solicitudes por parte del cliente y respuestas por parte del servidor proxy.

            \begin{eqnarray*}
                mensaje  & = &\,\,Solicitud\,\,|\,\,Respuesta\nonumber\\
            \end{eqnarray*}

        \subsubsection{Solictud}
        Una solicitud del cliente al servidor proxy incluye la versi\'on, el username y el password del usuario que actual.

        \begin{eqnarray*}
                Solicitud\ & = & \verb+"monitor"+\,\,SP\,\,Version\,\,SP\,\,User\,\,SP\,\,Password\,\,CRLF\nonumber\\
        \end{eqnarray*}

        \paragraph*{Version}
        La versi\'on del protocolo debe ser especificada. En caso de en un futuro querer extender el protocolo es util 
        poder asegurarse que versi\'on del protocolo soporta el cliente. As\'i, el protocolo podr\'a proveer la mayor 
        cantidad de informaci\'on posible de la mejor manera.

        \paragraph*{User y Password}
        User, el nombre del usuario, y password, su contraseña DEBEN ser provistos para iniciar la comunicaci\'on
        con este protocolo. El servidor autenticara estos datos para permiter o rechazar el monitoreo. Con el objetivo 
        de flexibilizar la aplicaci\'on, tanto el usuario como su contraseña PUEDEN ser confugirados en el archivo 
        .properties. Por defecto el usuario ser\'a "pdc" mientras que la constraseña ser\'a "pdcpass".
            
    \subsubsection{Respuesta}
    
    Los mensajes de respuesta tienen como contenido en primer lugar el c\'odigo de respuesta y en caso de ser un 
    pedido aceptado tambi\'en contendra la informaci\'on correspondiente al monitoreo.

    \begin{eqnarray*}
            Respuesta\ & = &i \verb+Mensaje\,\,de\,\,error+\,\,|\,\,\verb+Datos\,\,de\,\,monitoreo+\nonumber\\
    \end{eqnarray*}
    
    \paragraph*{Mensaje de error}
        El mensaje de error ser\'a un texto que dependiendo que imprime el error dependiendo de que fragemento del 
        protocolo no este siendo utilizado correctamente. Este mensaje puede venir acompañado de informaci\'on sobre el 
        correcto uso del protocolo. Para diferenciar el mensaje de error a los datos del monitoreo, el mensaje de error 
        sea cual sea contiene el mensaje "ERROR:" en la primer linea.

    \paragraph*{Datos de monitoreo}

    El protocolo tiene el potencial de proveer al usuario de ciertos datos del monitoreo del proxy que se 
    especifican a continuaci\'on

    \paragraph*{Total bytes transfered:} Cantidad total de bytes transferidos.
    \paragraph*{Bytes transfered between clients and proxy:} Bytes transferidos entre clientes y el proxy.
    \paragraph*{Bytes transfered between proxy and origin servers:} Bytes transferidos entre el proxy y los origin servers.
    \paragraph*{Total blocks:} Cantidad de filtros que fueron aplicados.
    \paragraph*{Total blocks with "All" condition:} Cantidad de pedidos bloqueados bajo reglas de tipo "All".
    \paragraph*{Total blocks from a single destiny IP:} Cantidad de pedidos filtrados por la direcci\'on IP destino.
    \paragraph*{Total blocks from a destiny IP group:} Cantidad de pedidos filtrados por grupos de IP destino.
    \paragraph*{Total blocks from a URI pattern:} Cantidad de pedidos filtrados por la URI.
    \paragraph*{Total blocks by Content-Type:} Cantidad de pedidos filtrados por el tipo de recurso.
    \paragraph*{Total blocks by resource size:} Cantidad de pedidos filtrados por tamaño.
    \paragraph*{Total l33t transformations:} Cantidad de conversiones a lenguaje L33t.
    \paragraph*{Total images rotated:} Cantidad de imagenes transformadas.
    \paragraph*{Open connections:} Cantidad de conexiones abiertas (clientes y origin server)

\newpage
    \subsection{Protocolo para acceder a la configuraci\'on del proxy}

        \paragraph*{Funcionamiento general}

        Este protocolo es un protocolo de pedido y respuesta con el objetivo modificar la 
        configuraci\'on actual del proxy en tiempo de ejecuci\'on. Tras cierto an\'alisis se decidi\'o que el 
        protocolo deb\'ia poseer la capacidad de devolver informaci\'on relevante en sus respuestas haciendo as\'i 
        el protocolo usable.

        El formato y la informaci\'on enviada tanto en el pedido como en la respuesta ser\'an 
        aclarados en secciones posteriores.

        Es necesario precisar que toda conexi\'on dada por este protocolo es iniciada por una aplicaci\'on cliente (por ejemplo netcat)
        y en este caso nuestra aplicaci\'on funciona de servidor, modificando la configuraci\'on del proxy 
        (si es que fue la acci\'on requerida) y retornando una respuesta.

        Para poder utilizar este protocolo se reserva un puerto especifico, el puerto $2021$, que debe ser conocido 
        por el cliente para poder establecer la conexi\'on. Con el objetivo de hacer nuestra aplicaci\'on flexible, 
        es posible configurar este puerto en el archivo .properties. No es exclusivo, pero se asume que este 
        protocolo es montado sobre TCP/IP, corroborando as\'i integridad y seguridad en la transferencia 
        de los datos.

        Por \'ultimo es \'util resaltar que en cada pedido de este protocolo se esta generando una nueva 
        conexi\'on y que al finalizar el pedido y la respuesta la conexi\'on se cierra..

        \subsubsection{Parametros del protocolo}
            El protocolo recibe ciertos parametros de tipos especificos. Los mismos se especifican a continuaci\'on y 
            queda en la responsabilidad del usuario utilizarlos correctamente. En el caso de direcciones IPS, las mismas 
            son validadas por el protocolo, pero en los casos de expresiones regulares y de \textit{Media Types} los 
            bloqueos simplemente trataran de hacerse comparando textos. El correcto uso de esstos dos valores queda a 
            cargo del usuario. A continuaci\'o se hace una especificaci\'on de estos tipos de datos:

            \paragraph*{Media Type}
            El protocolo usa \textit{Media Types} en el filtro para bloquear determinados tipos de datos, dado que es el mismo mecanismo para definir tipos de datos
            que utiliza el protocolo HTTP.

            \begin{eqnarray*}
                    media-type    & = & type "/" subtype \nonumber\\ %*( ";" parameter ) ???
                    type          & = & token\nonumber\\
                    subtype       & = & token\nonumber\\
            \end{eqnarray*}

            Los valores para $type$ y $subtype$ son \textit{case- insensitive}. 
            NO SE DEBE usar espacio linear en blanco (LWS) entre el tipo y el subtipo.

            \paragraph*{Expresiones Regulares}
            Algunos filtros reciben como par\'rametro expresiones regulares (por ejemplo para determinar las URIs bloqueadas). Estas expresiones regulares est\'an 
            basadas en el Basic Regular Expression (BRE) standard de IEE POSIX.
            Utilizaremos las expresiones regulares
            

            \paragraph*{Direcci\'on IP}
            Para ciertos filtros se utilizan direcciones IPs como par\'ametros. Las direcciones IPs utilizadas en esta especificaci\'on tienen la siguiente forma:

            \begin{eqnarray*}
                    ip-adress    & = &  number\,\,\verb+"."+\,\,number\,\,\verb+"."+\,\,number\,\,\verb+"."+\,\,number\nonumber\\
                    number       & = &  <valor decimal de un OCTET (0 - 255)>\nonumber\\
            \end{eqnarray*}
                
        \subsubsection{Mensaje del protocolo}

            \paragraph*{Tipos de mensaje}
            Los mensajes del protocolo consisten de solicitudes por parte del cliente y respuestas por parte del servidor proxy.

            \begin{eqnarray*}
                mensaje  & = &\,\,Solicitud\,\,|\,\,Respuesta\nonumber\\
            \end{eqnarray*}


        \subsubsection{Solicitud}
        Una solicitud del cliente al servidor proxy incluye la versi\'on y el tipo de operaci\'on a realizar sobre 
        las configuraciones. Dependiendo del tipo de operaci\'on puede ser necesario agregar par\'ametros adicionales.

%         config-filter n (operaci\'on) [parametros]
        \begin{eqnarray*}
                Solicitud\ & = & \verb+"config"+\,\,SP\,\,version\,\,SP\,\,operacion\,\,SP\,\,[parametros\,\,adicionales]\,\,CRLF\nonumber\\
        \end{eqnarray*}

         \paragraph*{Version}
        La versi\'on del protocolo debe ser especificada. En caso de en un futuro querer extender el protocolo es util 
        poder asegurarse que versi\'on del protocolo soporta el cliente. As\'i, el protocolo podr\'a proveer la mayor 
        cantidad de informaci\'on posible de la mejor manera.

        \paragraph*{Operaci\'on}
        La operaci\'on debe ser un n\'umero entero entre 1 y 6. Este n\'umero de operaci\'on representa lo siguiente:

        \begin{itemize}
            \item 1 --- Mostrar las reglas de bloqueos existentes.
            \item 2 --- Eliminar una regla de bloqueo. Esta operaci\'on DEBE tener par\'ametros adicionles.
            \item 3 --- Agregar una regla de bloqueo. Esta operaci\'on DEBE tener par\'ametros adicionales.
            \item 4 --- Modifica el estado de las rotaciones de imagenes, activando o desactivandolas.
            \item 5 --- Modifica el estado de las transformaciones a l33t, activando o desactivandolas.
            \item 6 --- Mostrar el estado de la configuraci\'on de las transformaciones.
        \end{itemize}

        \paragraph*{Par\'ametros adicionales}

        Los par\'ametros adicionales s\'olamente ser\'an tenidos en cuenta en caso de que la operaci\'on sea de 
        tipo 2 o de tipo 3. El formato ser\'a el que sigue:

        \begin{eqnarray*}
                Parametros adicionales\ & = &\,\,Id\,\,Regla\,\,|\,\,Codigo\,\,Filtro\,\,Cliente\,\,Filtro\,\,Cliente\,\,Codigo\,\,Filtro\,\,Server\,\,[Filtro\,\,Server]\nonumber\\
        \end{eqnarray*}
        
        En el caso de ser una operaci\'on de tipo 2 debe especificarse Id Regla. El Id Regla debe ser un n\'umero entero 
        que representa el identificador \'unico de la regla. Este puede verse listando las reglas mediante este
        protocolo.

        En caso de que la operaci\'on sea de tipo 3 deben especificarse el C\'odigo Filtro Cliente, el Filtro Cliente, el 
        C\'odigo Filtro Server y dependiendo de la regla el Filtro Server. Estos parametros deben aclararse ya que 
        cada regla de bloqueo se basa en una condici\'on a corroborar en el cliente y en una regla a corroborar en los 
        datos transeferidos. En caso de que el pedido y su respuesta coincidan con alguna regla de bloqueo, el proxy 
        devolvera una respuesta con el estado "Permission Denied". 
        A continuaci\'on se detallan los cuatro par\'ametros necesarios para generar una nueva regla de bloqueo.

        \paragraph*{C\'odigo Filtro Cliente y Filtro Cliente}

        El filtro en el cliente es parte de la condici\'on que se DEBE cumplir para que se aplique 
        el bloqueo. Esta parte del filtro se aplica sobre datos del cliente. El c\'odigo del filtro del cliente 
        DEBE ser un n\'umero entero entre 1 y 4 que especifica que tipo de filtro se aplicar\'a y se detalla a 
        continuaci\'on junto con el contenido del Filtro Cliente apropiado:

        \begin{itemize}
            \item 1 -- Filtro sobre una IP de origen. El Filtro Cliente deber ser una direcci\'on IP.
            \item 2 -- Filtro sobre un grupo de IPs de origen. El Filtro Cliente deben ser direcciones IP separadas por
            comas (",") sin espacios.
            \item 3 -- Filtro sobre un sistema operativo. El Filtro Cliente debe ser un texto especificando el 
            sistema operativo.
            \item 4 -- Filtro sobre un navegador. El Filtro Cliente debe ser un texto especificando el navegador.
        \end{itemize}
        
        \paragraph*{C\'odigo Filtro Server y Filtro Server}

        El filtro del server es parte de la condici\'on que se DEBE cumplir para que se aplique el bloqueo. 
        Esta parte del filtro se aplica sobre datos del pedido y de la respuesta. El c\'odigo del filtro del server 
        DEBE ser un n\'umero entero entre 1 y 6 que especifica que tipo de filtro se aplicar\'a y se detalla a 
        continuaci\'on junto con el contenido del Filtro Server apropiado:
        
        \begin{itemize}
            \item 1 -- Filtrado por ip destino. El Filtro Destino DEBE ser una direcci\'on IP.
            \item 2 -- Filtrado sobre un grupo de IPs destino. El Filtro Destino DEBEN ser direcciones IP separadas por 
            comas (",") sin espacios.
            \item 3 -- Filtrado de todos los pedidos. Este es el \'unico caso en donde no es necesario incluir Filtro Server.
            \item 4 -- Filtrado por Content-Type. El Filtro Destino DEBE ser un texto que va a compararse con el Content-Type de la respuesta.
            \item 5 -- Filtrado por tamaño aceptado. El Filtro Destino DEBE ser un n\'umero especificando el tamaño m\'aximo aceptado de un pedido.
            \item 6 -- Filtrado por URI. El Filtro Destino DEBE ser una expresi\'on regular a compararse con la URI destino.
        \end{itemize}

        \subsubsection{Respuesta}

        Despu\'es de recibir e interpretar un mensaje de solicitud, el servidor proxy responde con un mensaje de respuesta.
        
        \begin{eqnarray*}
           Respuesta    & = & Mensaje\,\,de\,\,error\,\,|\,\,Informacion\,\,de\,\,salida \nonumber\\
        \end{eqnarray*}

            \paragraph*{Mensaje de error}

                En caso de encontrarse un error en el pedido al protocolo se devolver\'a un mensaje de error comenzando 
                con la linea "ERROR:". A continuaci\'on se presentar\'a un detalle del error tratando de guiar al 
                usuario para poder realizar su pedido correctamente.

            \paragraph*{Informaci\'on de salida}

                Si el pedido es acorde al protocolo se devolver\'a un mensaje informativo dependiendo del tipo de 
                operaci\'on y dependiendo del estado del a configuraci\'on del proxy. Estos mensajes funcionan como 
                \textit{feedback} hacia el usuario confirmando el \'exito de su operaci\'on o la informaci\'on que fue 
                requerida.
        
        \subsubsection{Transformaciones a L33t}
%             transformar texto a formato l33t: Tendra que ser posible modificar el contenido de un recurso que dice ser text/plain realizando las siguientes sustituciones:
%                 *  a por 4 (cuatro)
%                 *  e por 3 (tres)
%                 *  i por 1 (uno)
%                 *  o por 0 (cero)
%             config-filter 6 (enable | disable)
            La activaci\'on de esta funcionalidad no implica ninguna clase de bloqueo sino la aplicaci\'on de una transformaci\'on de texto a formato \textit{l33t}. 
            Dicha transformaci\'on se aplica solo a los contenidos de los recursos que cuyo \textit{Media Type} sea \textit{text/plain}. 
            Los cambios a aplicar son los siguientes:
            \begin{itemize}
                \item Se reemplaza la letra $a$ o $A$ por un $4$ (cuatro).
                \item Se reemplaza la letra $e$ o $E$ por un $3$ (tres).
                \item Se reemplaza la letra $i$ o $I$ por un $1$ (uno).
                \item Se reemplaza la letra $o$ u $O$ por un $0$ (cero).
            \end{itemize}
            
            Como fue dicho ya en este informe el estado actual se consulta con la operaci\'on 6 y se modifica con la 
            operaci\'on 5.

        \subsubsection{Rotacio\'on de imagenes}
%             rotar 180 grados las imagenes: Se desea rotar imagenes 180 grados para sorprender a los usuarios que estan usando el proxy.
%             config-filter 7 (enable | disable)
            La activaci\'on de esta funcionalidad tampoco implica ninguna clase de bloqueo sino la aplicaci\'on de una transformaci\'on. 
            Dicha transformaci\'on concierne solamente a las im\'agenes y consiste en rotarlas 180 grados.
            Este m\'etodo no recibe par\'ametros.
     
            Como fue dicho ya en este informe el estado actual se consulta con la operaci\'on 6 y se modifica con la 
            operaci\'on 4.

\newpage

\section{Descripci\'on del diseño y de la arquitectura de la aplicaci\'on}
    Nuestra aplicaci\'on consiste de 3 \textit{threads}, uno para el manejo de la configuraci\'on, uno para el monitoreo y otro para el procesamiento de los 
    pedidos. Todos utilizando NIO. El uso de NIO permiti\'o manejar la entrada/salida de manera no bloqueante (gracias al \textit{Selector}) haciendo a 
    nuestro proxy concurrente. Sin embargo, dado que el procesamiento en s\'i se realiza en un \'unico thread, las operaciones complejas introducen tiempos muertos.

    El sistema de configuraci\'on es ejecutado en un thread aparte tambi\'en utilizando NIO. Lo mismo sucede con el 
    sistema de monitoreo.

    En las siguientes secciones se presentar\'a la estructura general de la aplicaci\'on resaltando las clases que 
    conforman el n\'ucleo del proxy. Adem\'as se dar\'a una vistazo del flujo y las transformaciones que sufren los 
    datos. 

    \subsection{Diagrama de clases}

    \begin{center}
    \includegraphics[scale = 0.6]{./images/clases.png}
    % clases.png: 939x356 pixel, 96dpi, 24.84x9.42 cm, bb=0 0 704 267
    \end{center}



    \subsection{Flujo y modificaciones en los datos}

    Tanto en un pedido como en una respuesta, la informaci\'on se lee de sockets de entrada a ByteBuffers. En ambos 
    casos, se genera una cola de ByteBuffers de donde ser\'a procesada la informaci\'on. Si bien la clase
    ProxySelectorProtocol es la encargada del manejo en s\'i de los sockets, la escritura y la lectura suceden en 
    UnidirectionalConnection (clase que se encarga de relacionar al proxy con un cliente o con un servidor).

    Cada UnidirectionalConnection posee un objeto Parser y un objeto Lexer, que en conjunto, pasando por un intermedio en 
    donde se trata a los datos como bytes, devuelven a UnidirectionalConection un modelo que es el mensaje Http parseado. 
    Este modelo es una lista de Tokens, definidos por nosotros, que tienen un tipo y la infromaci\'on en s\'i. Al haber 
    pasado por el parser, este modelo DEBE ser v\'alido.

    Una vez obtenido el modelo, es posible aplicar los filtros y transformaciones necesarias (ya sean las
    correspondientes a la configuraci\'on del proxy en s\'i o manipulaci\'on del mensaje Http original) que devuelven 
    un modelo modificado.

    Por \'ultimo, el modelo vuelve a ser llevado a una cola de ByteBuffers para poder ser transmitido en el socket de 
    escritura.

    \subsection{Clases distinguidas}
    
    	\subsubsection{ProtocolRunner}
    	
    		Es la clase donde se  manejan los eventos del selector de acuerdo al protocolo que se le especifica.
                Esta clase responde al patr\'on de diseño conocido como \textit{Reactor}, que maneja eventos de entrada/salida de manera concurrente.   
    		En nuestro sistema usamos esta clase con tres distintos protocolos (HTTP, configuracion y monitoreo). 
        
        \subsubsection{ProxySelectorProtocol}
			
			Se encarga del manejo de los sokets, activando y desactivando la lectura y la escritura sobre ellos, y 
			creando nuevos sockets cuando es nescesario.

			Tambien se encarga de la devoluci\'on de errores cuando los mensajes estan mal formado o cuando hay 
			algun error de algun tipo.		
			
        \subsubsection{Connection}
        
            El objeto Connection fue esencial en nuestro diseño. Esta clase es la encargada de relacionar a un cliente 
            con un servidor. As\'i, Connection contiene tanto el flujo de informaci\'on que va de cliente a servidor,
            como el flujo que va en el otro sentido (ambas son UnidirectionalConection).

            Este objeto, es instanciado una vez que es establecida la conexi\'on con el cliente, pasando a estar en un 
            estado "unestablished", solo listo para recivir informaci\'on del cliente. Una vez que el request es 
            \textit{parseado} correctamente, el objeto Connection pasa a un estado "established".

            Esta clase es manipulada para que pueda tratar correctamente con los casos de error.

        \subsubsection{UnidirectionalConnection}
        
			UnidirectionalConnection representa el flujo de informaci\'on, tanto de cliente a servidor, como de 
			servidor a cliente. Esta clase tiene el control de la informaci\'on desde que se leen del socket hasta 
			que se escriven en el otro socket.
			
			Parte de dicho flujo de informacion es el parseo, aplicacion de filtros y transformacion de la 
			informaci\'on. El parseo se delega en la clase HttpParser y la aplicacion de filtros en la clase
			ProxyConfiguration.

        \subsubsection{Modelo}
			
			La interfaz Modelo representa cualquier parte de un mensaje, o un mensaje entero. Sobre estos objetos se
			aplican los modelos y las transformaci\'ones, y se saben transformar a lista de ByteBuffers.			
			
        \subsubsection{Lexer y Tokens}
        	
        	El lexer( por medio de un ImputCharGetter) sabe transformar una fuente de informacion en una lista de Tokens.
        	Los Tokens, agrupan la informaci\'on, para faclilitarle el trabajo al Parser.

        \subsubsection{Parsers}
        
        	Parser es una interfaz, que se encarga( por medio de un Lexer) de transformar una fuente de informaci\'on, en 
        	un Model. Hay una gerarquia de parsers que se encargan de parsear diferentes secci\'ones de un mensaje.

%     \subsection{Aclaraciones adicionales}
 
			
\newpage
\section{Problemas encontrados y limitaciones de la aplicaci\'on}

    \subsection{Integraci\'on de NIO y multithreads}
        Desde un comienzo planteamos el proxy utilizando NIO y con la idea de hacerlo multithreading.
        
        La integraci\'on con NIO prob\'o no ser sencilla y tom\'o un tiempo comprenderla y contar con una versi\'on 
        estable del proxy original (proxy pasamanos).
        
        Si bien la idea original era utilizar m\'as de un thread de procesamiento, se nos hizo impracticable dadas las 
        sincronizaciones necesarias para que no haya problemas, y la gran complejidad de los requerimientos pedidos.
        
        Dada la naturaleza de NIO y como esta fue usada nos vimos capaces de facilitar un proxy concurrente. A pesar de 
        esto, esto podr\'ia ser mucho mejor explotado utilizando multiples threads. Por otro lado, el hecho de utilizar 
        un \'unico thread hace que la performance disminuya considerablemente. En casos de que el procesamiento sea 
        intenso (puede pasar por ejemplo al rotar una imagen), el thread quedar\'a bloqueado ejecutando esta acci\'on.
         
    \subsection{Conexiones persistentes}
        Uno de los requerimientos del trabajo pr\'actico era el de implementar conexiones persistentes con el servidor.

        La arquitectura que le dimos en un principio a la aplicaci\'on (que es la que se explica en el informe) nos 
        complic\'o de maneras importantes implementar este requerimiento (un ejemplo claro es que UnidirectinalConection 
        no termina de distinguir de una manera orientada a objetos, si la misma pertenece a un request o a un response).

        Al ver esta problematica, comenzamos un importante \textit{refactor} de la aplicaci\'on implementando conexiones 
        persistentes. A pesar del esfuerzo, al d\'ia de la fecha esta versi\'on es inestable y no funciona con algunos 
        sitios.

    \subsection{Transfer-Encoding}
        Es posible que llegue al proxy una respuesta que incluya el header \textit{Transfer-Encoding: chunked}. 
        Esto implica que el mensaje transmitido no tiene una longitud fija. Es necesario que nuestro proxy pueda reconstruir de manera correcta este
        mensaje para luego seguir proces\'andolo. Si bien varios enfoques fueron propuestos (transformar todo en un 
        gran chunk, procesar el contenido de a chunks y otros), el que fue elegido fue el de reconstruir el mensaje como 
        si tuviese el header "Content-Length". Esto nos facilit\'o enormemente a la hora de realizar las 
        transformaciones apropiadas. Como perdida, no estamos devolviendole al cliente lo que el origin server realmente 
        quiere darle y a la vez nos aleja m\'as de ser "fully compliant" con Http 1.1, por ejemplo, hace que el m\'etodo
        HEAD devuelva headers distintos a los que devolver\'ia GET.
    
    \subsection{Accept-Encoding}
        A la hora de realizar las transformaciones nos era una problematica importante recibir contenido 
        \textit{encodeado}. As\'i, en estos casos eliminamos del request el header Accept-Encoding, asegurando que el 
        contenido a recibirse va a poder ser analizado y transformado. Como negativa, esto hace perder performance ya que 
        el contenido por\'ia haber sido devuelto comprimido.

    \subsection{Multipart MIMEs}
    Existe la posibilidad de que la respuesta de un pedido sea de tipo \textit{multipart/*}. Nuestro proxy debe poder reconocer esta posibilidad y procesarla correctamente.
    Sin embargo, en este tipo de mensajes, nuestro proxy no es capaz de aplicar las transformaciones que sean pedidas.
    
    \subsection{Procesamiento de los mensajes}

    Uno de los problemas de nuestro proxy es que espera a tener el mensaje completo antes de comenzar a transmitirlo. 
    Esto se refleja de manera directa en una gr\'an disminuci\'on en la performance.

    \subsection{Compatibilidad con HTTP 1.0}
    Al \textit{parsear} los mensajes y al hacer pedidos a servidores, comenzamos a notar que hab\'ia serios problemas de 
    compatibilidad con HTTP 1.0.

    Ciertos arreglos debieron ser hechos para solucionar algunos de estos problemas mientras que otros no pudieron ser 
    del todo resueltos. Los pedidos a servidors HTTP 1.0 siguen siendo un problema en la versi\'on actual.

    \subsection{Conjuntos de ips} 

    Una de las opciones a tener en cuenta en los filtros era la de poder filtrar por grupos de ips. Actualmente esto se 
    realiza recibiendo una lista de ips separadas por comas (","). A pesar de que tratamos de mejorar el rendimiento 
    almacenandolas en TreeSet's, creemos que esto podr\'ia ser mejorado implementando conocimientos sobre m\'ascaras.

    \subsection{Manejo de errores}

    Una problematica que surgi\'o en el desarrollo era la del comportamiento esperado al detectar errores. En caso de que 
    un pedido o una respuesta no corresponda al protocolo HTTP, deba ser filtrada o posea alg\'un otro tipo de error era 
    necesario devolverle al cliente un mensaje de error de acuerdo al protocolo HTTP.

    As\'i, desarrollamos respuestas \textit{custom} que contienen el c\'odigo de respuesta correcto para cada estado.

    \subsection{Administraci\'on de ByteBuffers}
    Por como se maneja NIO, debimos implementar un sistema de manejo de buffers (ByteBuffers de NIO), para manejar el hecho de que tanto la lectura como la 
    escritura se hacen de a "pedazos" o segmentos. Para esto tenemos un \textit{pool} de ByteBuffers, que además puede incrementar su tamaño
    hasta un determinado l\'imite, y adem\'as volver luego al tamaño previo.

    \subsection{M\'etodos soportados}

    Actualmente, nuestro proxy soporta forwarding de los m\'etodos GET, HEAD y POST. Ser\'ia correcto que los otros 
    m\'etodos sean implementados en nuestra aplicaci\'on.

    \subsection{Pipe-Lining}

    Podr\'ia ser una ampl\'ia mejora a la performance implementarle Pipe-Lining al proxy. Sin embargo, la versi\'on 
    actual no cuenta con esta propiedad.

    \subsection{Cache}

    La implementaci\'on de un buen sistema de \textit{cacheo} tambi\'en agregar\'ia una importante mejora en el 
    rendimiento del proxy. Sin embargo, esta versi\'on del proxy tampoco cuenta con esta funcionalidad.

    \subsection{Conexiones concurrentes}

    Si bien nuestro proxy provee un sistema de conexiones concurrentes a trav\'es de NIO, el rendimiento del mismo
    comienza a deteriorarse al realizar muchas conexiones concurrentes. Tr\'as ciertas pruebas de performance, es posible 
    decir que este n\'umero ronda por las 100 conexiones concurrentes.
\newpage

\section{Performance}

Dada nuestra decisi\'on de tener un solo \textit{thread} de procesamiento, nuestra performance no es bajo ning\'un punto de vista \'optima. A pesar de soportar 
conexiones concurrentes, al momento de procesar un mensaje, al ser un solo \textit{thread}, tenemos tiempos muertos considerables, dado que podr\'ian estar 
ejecut\'andose otras operaciones de otras conexiones en otros \textit{threads}. Una desventaja evidente de nuestro sistema es, por lo tanto, que al cargar o rotar
im\'agenes, no hacemos otro trabajo que \'este (lo cual puede resultar especialmente malo con archivos grandes).

Otro punto flojo es que al no poder terminar de hacer estable nuestro versi\'on con un \textit{pool} de conexiones persistentes, no estamos aprovechando el gran poder
que nos ofrece este tipo de conexiones. Las páginas que logramos cargar con esta versi\'on y los pocas pruebas exitosas que hicimos mostraron una visible mejora en los
tiempos de respuesta.

    \subsection{Pruebas de performance}
    Para medir nuestra performance utilizamos \textit{ApacheBench}. Dado que por nuestro diseño, la perfomance no era nuestra principal preocupaci\'on, y ante 
    la gran cantidad de problemas encontrados y la falta de tiempo para solucionarlos, no pudimos crear distinos escenarios. Aún asi, hicimos varios 
    test de carga con un host remoto (\textit{yahoo}) y test de stress con un host local (servidor \textit{nginx}).\\

    Los tests de carga, arrojaron un promedio de alrededor de 5 requests por segundo utilizando nuestro proxy, contra alrededor de 110, sin pasar por el proxy.
    En este tipo de escenario, el proxy funciona de manera estable hasta poco menos de 100 conexiones concurrentes.\\

    Los tests de stress, arrojaron un promedio de alrededor de 950 requests por segundo utilizando el proxy, contra 12000, sin pasar por el proxy. En este 
    tipo de escenario, el proxy funciona de manera estable hasta las 1000 conexiones concurrentes.\\
    
    Para m\'as informaci\'on, referirse a la carpeta \textit{doc/benchmarks}.
    
\newpage

\section{Posibles extensiones}
    \begin{itemize}
        \item Implementaci\'on de procesamiento multi-thread.
        \item Implementaci\'on de pipe-lining.
        \item Implementaci\'on de cache.
        \item Implementaci\'on de m\'etodos.
        \item Implementaci\'on de nuevos filtros y transformaciones.
        \item Obtenci\'on de una versi\'on estable con conexiones persistentes a los servidores.
        \item Mejoras en el funcionamiento para ser "Fully Compliant" con HTTP 1.1.
    \end{itemize}
\newpage

\section{Conclusiones}
    A la hora de desorrollar el trabajo pr\'actico nos result\'o muy interesante el estudio y an\'alisis el protocolo 
    HTTP. Tanto en la etapa de an\'alisis como en la de implementaci\'on descubrimos y solucionamos distintos tipos de 
    detalles. Se hizo natural en el desarrollo, encontrar trabas que nuestro proxy sufr\'ia debido a particularidades 
    del protocolo. Estos momentos derivaban en investigaci\'on concreta del funcionamiento de HTTP, de formatos y de 
    headers particulares, haciendo posible entender que representa cada parte del protocolo. Era natural a su vez 
    derivar de estos momentos una conclusi\'on de cual era la raz\'on de la existencia de estos detalles, proporcionando 
    una nueva dimensi\'on del poder de HTTP.\\

    A su vez, fue enriquecedor ver como ciertas de estas funcionalidades no estan especificadas por el RFC y sin embargo 
    fueron adoptadas por la comunidad. De nuevo fue una grata sorpresa ver como se extend\'ia la funcionalidad de HTTP 
    a trav\'es del trabajo comunitario pero da a preguntarse si el protocolo HTTP no deber\'ia ser actualizado dandole 
    a los usuarios mayor flexibilidad y potencia, adecuado a los cambios de hoy en d\'ia y a los pedidos de los usuarios.\\

    NIO nos acercó a una manera distinta de manejar la entrada y salida a la que estabamos acostumbrados.\\

    El procesamiento de datos de la red es 
    importante y se debe tener en cuenta el caso de que los segmentos TCP pueden llegar de manera que un mensaje de nivel de aplicación queda 
    interrumpido cuando el sistema operativo lo devuelve, por lo tanto hay que tener un sistema de buffering para que se lean mensajes completos.\\

    La correcta utilización y aprevochamiento de las conexiones persistentes mejora de forma notable la perfomance, aunque en nuestra versi\'on final
    esto no pueda ser observado.\\

    El diseño de los protocolos de configuración y monitoreo nos resultó un lindo desafío, el que cual requirió de nuestra creatividad e inventiva, 
    además de darnos una muestra de las complicaciones de desarrollar un protocolo desde cero.\\

\newpage
\section{Aplicaciones y herramientas para desarrollo y testing}

A continuaci\'on se presentan algunas aplicaciones y herramientas varias que ser\'an \'utiles a lo largo del trabajo.

\begin{itemize}
 \item \textbf{Netcat}, para usarlo como aplicaci\'on cliente y hacer determinadas solicitudes, tambi\'en como posible servidor.
 \item \textbf{Curl}, para hacer algo similar.
 \item \textbf{User Agents} (Mozilla Firefox, Google Chrome), para probar nuestro proxy con clientes ''de la vida real``.
 \item \textbf{Plugins de Firefox} (como Http-fox, Tamper Data, Firebugs, para ver estado de los requests, los headers y manipularlos.)
 \item \textbf{ApacheBench}, para hacer pruebas de performance y \textit{benchmarking}.
 \item \textbf{Wireshark}, para ver el contenido de paquetes y detectar errores o confirmar ideas.
 \item \textbf{Nginx}, para usar como servidor HTTP local y hacer tests de stress.
\end{itemize}

\newpage
\section{Casos de prueba}

    \subsection{Solicitudes inv\'alidas}
    Usando la herramienta \textit{netcat} podemos comprobar que el proxy se comporta de maner esperada cuando recibe solicitudes con m\'etodos
    que no soporta, devolviendo el status code apropiado. (m\'etodo \textit{TRACE})

    \subsection{Integraci\'on con User Agents}
    Para verificar que nuestro proxy se puede usar ''en la vida real``, es posible configurar distintos browsers para que lo utilicen.
    As\'i, se puede tener una buena apreciaci\'on de como se comporta el proxy en una situaci\'on de trabajo.
    Este tipo de pruebas pueden utilizarse para ver de forma sencilla la aplicaci\'on de bloqueos y transformaciones.

    \subsection{Casos extraños}
    Utilizando \textit{netcat}, probaremos casos de escasa ocurrencia pero que sin embargo el protocolo HTTP considera v\'alidos. Por ejemplo, 
    campos de m\'as de una l\'inea, headers repetidos, headers faltantes, etc...
    Varios de estos casos pueden reproducirse utilizando el \textit{plug-in} de Firefox, Tamper Data.

\newpage

\section{Anexo}

    \subsection{Gu\'ia de instalaci\'on}
    
    Para la compilaci\'on se requiere tener instalado Maven. Para compilar correr el comando \textbf{mvn clean package}, en la ra\'iz del proyecto.\\

    Una vez compilado, el \textit{.jar} se encontrará en la carpeta \textit{target} del proyecto. Para correr el programa ejecuar
    el comando \textit{java -jar target/http-proxy-0.0.1-SNAPSHOT-jar-with-dependencies.jar}.

    Ante cualquier duda referirse al archivo \textit{README.md}.

    \subsection{Ejemplos de configuraci\'on}

    El archivo de configuraci\'on es un archivo \textit{properties} que se encuentra bajo la carpeta \textit{src/main/resources} con el nombre 
    \textit{proxy.properties}. Tal archivo contiene las siguientes propiedades, (los valores default aparecen entre par\'entesis):

    \begin{itemize}
        \item \textbf{proxy\_ports} - (8081) - Puertos de escucha de conexiones entrantes del proxy (eventualmente podrían ser más de uno). 
                                  Es una lista de puertos, separadas por comas.
        \item \textbf{monitoring\_ports} - (2020) - Puerto de escucha del protocolo de monitoreo.
        \item \textbf{config\_ports} - {2021} - Puerto de escucha del protocolo de configuraci\'on del proxy.
        \item \textbf{username} - {pdc} - Nombre de usuario para acceder a la informaci\'on de monitoreo.
        \item \textbf{password} - {pdcpas} - Contraseña para acceder a la informaci\'on de monitoreo.
        \item \textbf{buffer\_cant} - {2048} - Cantidad de \textit{ByteBuffers} allocados inicialmente.
        \item \textbf{buffer\_max} - {4096} - M\'axima cantidad de \textit{ByteBuffers} que se pueden allocar.
        \item \textbf{buffer\_size} - {4096} - Tamaño, en bytes, de buffer de cada \textit{ByteBuffer}.

    \end{itemize}

    Todas estas propiedades tienen valores \textit{default}, por lo que si no se encuentran en el archivo, o tienen valores incoherentes se aplican los
    valores por defecto.

\end{document}
